/**********************************************************************/
#include <QXmlStreamReader>
/**********************************************************************/
#include "chatserver.h"
#include "chatclient.h"

/**********************************************************************/
#define SOCK "net: "
#define PROT "pro: "

/**********************************************************************/
ChatServer::ChatServer()
{
}

/**********************************************************************/
void ChatServer::start (quint16 port)
{
  if (!listen (QHostAddress::Any, port))
  {
    emit error(QString("Error to listen on port %1").arg(port));
    return;
  }

  printToProtocol(SOCK,
                  QString("server started on port: %1").arg(port));
}

/**********************************************************************/
void ChatServer::stop ()
{
  for(int i = 0; i < clientList.size(); ++i)
    clientList.at(i)->close();
  close ();

  printToProtocol(SOCK, "server stopped.");
}

/**********************************************************************/
void ChatServer::distributeData(ChatClient *client)
{
  QByteArray data;

  while(!client->atEnd())
    data += client->readAll();

  checkData(client, data);

  if(!data.isEmpty())
    for(int i = 0; i < clientList.size(); ++i)
      clientList.at(i)->write(data);
}

/**********************************************************************/
void ChatServer::printToProtocol(char *type, QString msg)
{
  emit protocolMessage(QString(type + msg));
}

/**********************************************************************/
void ChatServer::checkData(ChatClient *client, QByteArray data)
{
  QXmlStreamReader xml(data);

  while(!xml.atEnd())
  {
    xml.readNext();
    if(!xml.error())
    {
      if(xml.name() == "from")
        if(client->getNickname().isEmpty())
          client->setNickname(QString(
              QByteArray::fromBase64(xml.readElementText().toAscii())));

      if(xml.name() == "announce")
      {
        QString text = xml.readElementText();
        if(text == "alive")
         printToProtocol(PROT,
                         client->getNickname() + " is still alive!");

        if(text == "login")
          emit clientAdded(client->getNickname());
      }

      if(xml.name() == "msg")
        printToProtocol(PROT,
                        client->getNickname() + ": " + QString(
                        QByteArray::fromBase64(
                            xml.readElementText().toAscii())));
    }
  }
}

/**********************************************************************/
void ChatServer::forwardError(QString msg)
{
  emit error(msg);
}

/**********************************************************************/
void ChatServer::incomingConnection(int socketDescriptor)
{
  ChatClient *client = new ChatClient();

  printToProtocol(SOCK, "creating new client socket...");

  connect(client, SIGNAL(dataReceived(ChatClient *)), this,
                  SLOT(distributeData(ChatClient *)));
  connect(client, SIGNAL(error(QString)), this,
                  SLOT(forwardError(QString)));

  printToProtocol(SOCK, "adding client to list...");

  clientList.append(client);
  client->setReady(socketDescriptor);
}
